package com.autoagent.ai_live_master.common.utils;


import com.autoagent.ai_live_master.common.config.ApiConfig;
import com.autoagent.ai_live_master.common.model.Payload;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.*;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.time.Duration;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class AgentClient {

    private ApiConfig apiConfig;
    
    @NonNull
    private String apiKey;
    @NonNull
    private String apiSecret;
    @NonNull
    private String agentId;

    private MessageListener listener;

    public void setMessageListener(MessageListener listener) {
        this.listener = listener;
    }
    
    /**
     * 创建一个新的Payload对象
     * @param userChatInput 用户输入的文本内容（必需）
     * @return 包含必要参数的Payload对象
     */
    public Payload createPayload(String userChatInput) {
        return Payload.builder()
                .agentId(this.agentId)
                .userChatInput(userChatInput)
                .build();
    }

    /**
     * 发送聊天请求到API
     * @param payload 包含请求参数的Payload对象
     * @return API响应
     * @throws Exception 如果请求过程中发生错误
     */
    public String chat_completions(Payload payload) throws Exception {
        String url = apiConfig.getHost() + "/openapi/agents/chat/completions/v1";
        System.out.println(url);
        ObjectMapper mapper = new ObjectMapper();
        String jsonPayload = mapper.writeValueAsString(payload);
        
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .header("Authorization", String.format("Bearer %s.%s", this.apiKey, this.apiSecret))
                .header("Content-Type", "application/json")
                .POST(HttpRequest.BodyPublishers.ofString(jsonPayload))
                .build();
        
        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
        
        // 检查响应状态码
        if (response.statusCode() != 200) {
            throw new Exception(String.format("Agent API error: %d, %s", response.statusCode(), response.body()));
        }
        
        // 解析响应内容
        JsonNode responseJson = mapper.readTree(response.body());
        JsonNode choices = responseJson.get("choices");
        if (choices != null && choices.isArray() && !choices.isEmpty()) {
            JsonNode content = choices.get(0).get("content");
            if (content != null) {
                return content.asText();
            }
        }
        
        throw new Exception("Invalid response format");
    }
    /**
     * 发送异步聊天请求到API
     * @param payload 包含请求参数的Payload对象
     * @return 请求ID (requestId)
     * @throws Exception 如果请求过程中发生错误
     */
    public String chat_completions_async(Payload payload) throws Exception {
        String url = apiConfig.getHost() + "/openapi/agents/chat/completions/async/v1";
        ObjectMapper mapper = new ObjectMapper();
        String jsonPayload = mapper.writeValueAsString(payload);

        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .header("Authorization", String.format("Bearer %s.%s", this.apiKey, this.apiSecret))
                .header("Content-Type", "application/json")
                .POST(HttpRequest.BodyPublishers.ofString(jsonPayload))
                .build();

        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

        // 检查响应状态码
        if (response.statusCode() != 200) {
            throw new Exception(String.format("Agent API error: %d, %s", response.statusCode(), response.body()));
        }

        // 解析响应内容
        JsonNode responseJson = mapper.readTree(response.body());
        JsonNode data = responseJson.get("data");
        if (data != null) {
            JsonNode requestId = data.get("requestId");
            if (requestId != null) {
                return requestId.asText();
            }
        }

        throw new Exception("Invalid response format: requestId not found");
    }

    /**
     * 轮询异步聊天请求的结果
     * @param requestId 异步请求ID
     * @return 聊天内容
     * @throws Exception 如果请求过程中发生错误
     */
    public String chat_completions_async_polling(String requestId) throws Exception {
        String url = String.format("%s/openapi/agents/chat/completions/async/polling/v1?agentId=%s&requestId=%s",
                apiConfig.getHost(), this.agentId, requestId);

        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .header("Authorization", String.format("Bearer %s.%s", this.apiKey, this.apiSecret))
                .GET()
                .build();

        while (true) {
            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
            
            // 检查响应状态码
            if (response.statusCode() != 200) {
                throw new Exception(String.format("Agent API error: %d, %s", response.statusCode(), response.body()));
            }

            // 解析响应内容
            ObjectMapper mapper = new ObjectMapper();
            JsonNode responseJson = mapper.readTree(response.body());
            
            // 检查响应码
            if (responseJson.get("code").asInt() != 1) {
                throw new Exception(String.format("API业务错误: %s", responseJson.get("msg").asText()));
            }

            JsonNode data = responseJson.get("data");
            if (data != null) {
                int state = data.get("state").asInt();
                
                switch (state) {
                    case 0: // NOT_EXIST
                        throw new Exception("请求不存在");
                    case 1: // RUNNING
                        Thread.sleep(1000); // 等待1秒后继续轮询
                        continue;
                    case 2: // DONE
                        JsonNode output = data.get("output");
                        if (output != null) {
                            JsonNode choices = output.get("choices");
                            if (choices != null && choices.isArray() && !choices.isEmpty()) {
                                JsonNode content = choices.get(0).get("content");
                                if (content != null) {
                                    return content.asText();
                                }
                            }
                        }
                        break;
                    case 3: // EXCEPTION
                        throw new Exception("请求处理异常");
                    default:
                        throw new Exception("未知的状态码: " + state);
                }
            }

            throw new Exception("Invalid response format: content not found");
        }
    }
    /**
     * 发送同步流式聊天请求到 API（Server-Sent Events / 长连接方式）
     * @param payload 请求体参数
     * @throws Exception 异常处理
     */
    public void chat_completions_streaming(Payload payload) throws Exception {
        String url = apiConfig.getHost() + "/openapi/agents/chat/stream/v1";
        System.out.println("Streaming URL: " + url);

        ObjectMapper mapper = new ObjectMapper();
        String jsonPayload = mapper.writeValueAsString(payload);

        HttpClient client = HttpClient.newBuilder()
                .connectTimeout(Duration.ofSeconds(10))
                .build();

        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .header("Authorization", String.format("Bearer %s.%s", this.apiKey, this.apiSecret))
                .header("Content-Type", "application/json")
                .header("Accept", "text/event-stream")
                .POST(HttpRequest.BodyPublishers.ofString(jsonPayload))
                .build();

        HttpResponse<InputStream> response;
        try {
            response = client.send(request, HttpResponse.BodyHandlers.ofInputStream());
        } catch (Exception e) {
            if (listener != null) listener.onError(e);
            throw e;
        }

        try (BufferedReader reader = new BufferedReader(new InputStreamReader(response.body(), StandardCharsets.UTF_8))) {
            String line;
            while ((line = reader.readLine()) != null) {
                if (!line.startsWith("data:")) {
                    continue; // 跳过无关内容
                }

                String json = line.substring(5).trim(); // 截取 data: 后面的内容

                try {
                    JsonNode node = mapper.readTree(json);
                    String type = node.path("type").asText();
                    String content = node.path("content").asText();

                    if ("text".equals(type) && content != null && !content.isEmpty()) {
                        if (listener != null) {
                            listener.onMessage(content); // 推送流式片段
                        }
                    }

                    boolean complete = node.path("complete").asBoolean(false);
                    boolean finish = node.path("finish").asBoolean(false);
                    if (complete || finish) {
                        if (listener != null) {
                            listener.onComplete(); // 通知完成
                        }
                        break; // 正常结束，退出循环
                    }

                } catch (Exception e) {
                    System.err.println("解析 JSON 失败: " + e.getMessage());
                    if (listener != null) {
                        listener.onError(e); // JSON 解析错误也通知
                    }
                }
            }
        } catch (Exception e) {
            if (listener != null) {
                listener.onError(e); // 流处理时出错
            }
            throw e;
        }
    }

}